package com.ruoyi.depot.service.impl;

import java.text.SimpleDateFormat;
import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.commodity.domain.Product;
import com.ruoyi.commodity.domain.ProductImage;
import com.ruoyi.commodity.mapper.ProductImageMapper;
import com.ruoyi.commodity.mapper.ProductMapper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.OrdersProduct;
import com.ruoyi.common.enums.QualityCheckStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.depot.domain.DTOReceiptProducts;
import com.ruoyi.depot.domain.ReceiptProducts;
import com.ruoyi.depot.domain.dto.OrdersProductUpdateDTO;
import com.ruoyi.depot.domain.vo.OrdersProductVO;
import com.ruoyi.depot.domain.vo.ReceiptProductVO;
import com.ruoyi.depot.mapper.OrdersProductMapper;
import com.ruoyi.depot.mapper.ReceiptProductsMapper;
import com.ruoyi.depot.mapper.VoOrdersProductMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.stream.Collectors;

import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.depot.mapper.ReceiptMapper;
import com.ruoyi.depot.domain.Receipt;
import com.ruoyi.depot.service.IReceiptService;

import javax.annotation.Resource;

/**
 * 收货单Service业务层处理
 *
 * @author ruoyi
 * @date 2023-12-26
 */
@Service
public class ReceiptServiceImpl extends ServiceImpl<ReceiptMapper, Receipt> implements IReceiptService {
	@Resource
	private ReceiptMapper receiptMapper;

	@Resource
	private VoOrdersProductMapper voOrdersProductMapper;

	@Resource
	private ProductMapper productMapper;

	@Autowired
	private OrdersProductMapper ordersProductMapper;

	@Autowired
	private ReceiptProductsMapper receiptProductsMapper;

	@Autowired
	private ProductImageMapper productImageMapper;

	/**
	 * 点击质检、免检、收货按钮时查询收货单
	 *
	 * @param receiptId 收货单主键
	 * @return 收货单
	 */
	@Override
	public Receipt selectReceiptByReceiptId(String receiptId) {
		Receipt receipt = receiptMapper.selectReceiptByReceiptId(receiptId);

		if (!receipt.getDtoReceiptProductsList().isEmpty()) {
			// 查询产品图片
			Map<Integer, List<String>> productImages = productImageMapper.selectProductImagesByProductId(
							receipt.getDtoReceiptProductsList().stream().map(DTOReceiptProducts::getProductId).collect(Collectors.toList())
					).stream()
					.collect(Collectors.groupingBy(ProductImage::getProductId, Collectors.mapping(ProductImage::getProductImagePath, Collectors.toList())));

			// 分配产品图片
			for (DTOReceiptProducts receiptProducts : receipt.getDtoReceiptProductsList()) {
				receiptProducts.setImgName(productImages.get(receiptProducts.getProductId().intValue()));
			}

			// 调用合并方法，将 DTOReceiptProductsList 按照 SKU 和 receiptId 分组合并
			List<DTOReceiptProducts> mergedProducts = mergeReceiptProducts(receipt.getDtoReceiptProductsList());

			// 将合并后的数据重新设置到收货单对象中
			receipt.setDtoReceiptProductsList(mergedProducts);
		}
		return receipt;
	}

	/**
	 * 点击修改按钮时查询收货单
	 *
	 * @param receiptId 收货单主键
	 * @return 收货单
	 */
	@Override
	public Receipt selectUpdateReceiptByReceiptId(String receiptId) {
		Receipt receipt = receiptMapper.selectReceiptByReceiptId(receiptId);

		if (!receipt.getDtoReceiptProductsList().isEmpty()) {
			// 查询产品图片
			Map<Integer, List<String>> productImages = productImageMapper.selectProductImagesByProductId(
							receipt.getDtoReceiptProductsList().stream().map(DTOReceiptProducts::getProductId).collect(Collectors.toList())
					).stream()
					.collect(Collectors.groupingBy(ProductImage::getProductId, Collectors.mapping(ProductImage::getProductImagePath, Collectors.toList())));

			// 分配产品图片
			for (DTOReceiptProducts receiptProducts : receipt.getDtoReceiptProductsList()) {
				receiptProducts.setImgName(productImages.get(receiptProducts.getProductId().intValue()));
			}
		}
		return receipt;
	}

	/**
	 * 查询收货单列表
	 *
	 * @param receipt 收货单
	 * @return 收货单
	 */
	@Override
	public List<Receipt> selectReceiptList(Receipt receipt) {
		// 查询收货单列表
		List<Receipt> receiptList = receiptMapper.selectReceiptList(receipt);
		if (receiptList == null || receiptList.isEmpty()) {
			return receiptList;
		}

		// 提取所有收货单ID
		List<String> receiptIds = receiptList.stream()
				.map(Receipt::getReceiptId)
				.collect(Collectors.toList());

		// 根据收货单ID查询对应的收货单明细
		List<DTOReceiptProducts> dtoReceiptProducts = receiptMapper.selectReceiptListById(receiptIds);
		dtoReceiptProducts.sort(Comparator.comparing(DTOReceiptProducts::getSku));

		// 对每一个收货单下面的明细的一个SKU对多个GTIN的明细进行汇总显示成一条产品数据
		List<DTOReceiptProducts> list = mergeReceiptProducts(dtoReceiptProducts);
		// 按照收货单ID分组
		Map<String, List<DTOReceiptProducts>> receiptProductsMap = list.stream()
				.collect(Collectors.groupingBy(DTOReceiptProducts::getReceiptId));

		// 提取去重后的产品ID列表
		List<Long> productIds = list.stream()
				.map(DTOReceiptProducts::getProductId)
				.distinct()
				.collect(Collectors.toList());

		// 查询所有产品图片路径
		List<ProductImage> productImages = productImageMapper.selectProductImagesByProductId(productIds);

		// 按照产品ID分组，映射到图片路径列表
		Map<Integer, List<String>> productImageMap = productImages.stream()
				.collect(Collectors.groupingBy(ProductImage::getProductId,
						Collectors.mapping(ProductImage::getProductImagePath, Collectors.toList())));

		// 为每个收货单明细设置图片（取第一张）
		list.forEach(receiptProduct -> {
			List<String> images = productImageMap.get(receiptProduct.getProductId().intValue());
			if (images != null && !images.isEmpty()) {
				receiptProduct.setImgName(images);
			}
		});

		// 将分组后的收货单明细赋值到对应的收货单中
		receiptList.forEach(r -> r.setDtoReceiptProductsList(receiptProductsMap.get(r.getReceiptId())));

		return receiptList;
	}

	/**
	 * 根据 SKU 和 receiptId 分组合并 DTOReceiptProducts 数据
	 *
	 * @param dtoList 原始收货单明细数据列表
	 * @return 合并后的数据列表，每个分组只有一条记录，数量字段累加，GTIN 汇总到一个集合属性中
	 */
	public static List<DTOReceiptProducts> mergeReceiptProducts(List<DTOReceiptProducts> dtoList) {
		if (dtoList == null || dtoList.isEmpty()) {
			return Collections.emptyList();
		}

		// 按照 SKU 和 receiptId 组合分组：格式为 sku_receiptId
		Map<String, List<DTOReceiptProducts>> groupedMap = dtoList.stream()
				.collect(Collectors.groupingBy(item -> item.getSku() + "_" + item.getReceiptId()));

		List<DTOReceiptProducts> mergedList = new ArrayList<>();

		for (Map.Entry<String, List<DTOReceiptProducts>> entry : groupedMap.entrySet()) {
			List<DTOReceiptProducts> group = entry.getValue();
			// 取分组中的第一条记录作为基础数据（如 SKU、receiptId、productId 等字段）
			DTOReceiptProducts merged = new DTOReceiptProducts();
			BeanUtils.copyProperties(group.get(0), merged);
			merged.setSku(group.get(0).getSku());
			merged.setReceiptId(group.get(0).getReceiptId());
			merged.setProductId(group.get(0).getProductId());
			merged.setProductName(group.get(0).getProductName());
			merged.setImgName(group.get(0).getImgName());
			merged.setProductProNo(group.get(0).getProductProNo());
			merged.setReceiptProductId(group.get(0).getReceiptProductId());
			String qualityStatus;
			if (group.stream().allMatch(g -> g.getQualityStatus().equals(QualityCheckStatus.COMPLETED.getCode()))) {
				qualityStatus = QualityCheckStatus.COMPLETED.getCode();
			} else {
				// 检查是否有状态为 IN_PROGRESS 的元素
				boolean hasZeroStatus = group.stream().anyMatch(g -> g.getQualityStatus().equals(QualityCheckStatus.IN_PROGRESS.getCode()));
				if (hasZeroStatus) {
					qualityStatus = QualityCheckStatus.IN_PROGRESS.getCode();
				}
				// 如果没有 IN_PROGRESS 状态，检查是否有状态为 PARTIALLY_INSPECTED 的元素
				else {
					boolean hasFiveStatus = group.stream().anyMatch(g -> g.getQualityStatus().equals(QualityCheckStatus.PARTIALLY_INSPECTED.getCode()));
					if (hasFiveStatus) {
						qualityStatus = QualityCheckStatus.PARTIALLY_INSPECTED.getCode();
					}
					// 如果都没有，则返回 NOT_INSPECTED
					else {
						qualityStatus = QualityCheckStatus.NOT_INSPECTED.getCode();
					}
				}
			}
			merged.setQualityStatus(qualityStatus);

			// 其它基础字段可按需求赋值

			// 数量字段累加（注意空值处理，这里都按 Long 类型处理，可根据业务调整）
			long totalNotificationQuantity = group.stream()
					.mapToLong(item -> item.getNotificationQuantity() != null ? item.getNotificationQuantity() : 0L)
					.sum();
			long totalReceiptQuantity = group.stream()
					.mapToLong(item -> item.getReceiptQuantity() != null ? item.getReceiptQuantity() : 0L)
					.sum();
			long totalPendingQuantity = group.stream()
					.mapToLong(item -> item.getPendingQuantity() != null ? item.getPendingQuantity() : 0L)
					.sum();
			long totalNotInspected = group.stream()
					.mapToLong(item -> item.getNotInspected() != null ? item.getNotInspected() : 0L)
					.sum();
			long totalQualityInspection = group.stream()
					.mapToLong(item -> item.getQualityInspection() != null ? item.getQualityInspection() : 0L)
					.sum();
			long totalCheckedQuantity = group.stream()
					.mapToLong(item -> item.getCheckedQuantity() != null ? item.getCheckedQuantity() : 0L)
					.sum();
			long totalAvailableQuantity = group.stream()
					.mapToLong(item -> item.getAvailableQuantity() != null ? item.getAvailableQuantity() : 0L)
					.sum();
			long totalDefectiveQuantity = group.stream()
					.mapToLong(item -> item.getDefectiveQuantity() != null ? item.getDefectiveQuantity() : 0L)
					.sum();

			merged.setNotificationQuantity(totalNotificationQuantity);
			merged.setReceiptQuantity(totalReceiptQuantity);
			merged.setPendingQuantity(totalPendingQuantity);
			merged.setNotInspected(totalNotInspected);
			merged.setQualityInspection(totalQualityInspection);
			merged.setCheckedQuantity(totalCheckedQuantity);
			merged.setAvailableQuantity(totalAvailableQuantity);
			merged.setDefectiveQuantity(totalDefectiveQuantity);

			// 汇总 GTIN：过滤掉 null 值，并去重
			List<String> gtinList = group.stream()
					.map(DTOReceiptProducts::getGtin)
					.filter(Objects::nonNull)
					.distinct()
					.collect(Collectors.toList());
			// 假设 DTOReceiptProducts 类中有 gtins 属性以及相应的 setter 方法
			merged.setGtins(gtinList);

			mergedList.add(merged);
		}

		return mergedList;
	}

	/**
	 * 新增收货单
	 *
	 * @param receipt 收货单
	 * @return 结果
	 */
	@Transactional(timeout = 30)
	@Override
	public int insertReceipt(Receipt receipt) {
		receipt.setReceiptId(IdUtils.fastSimpleUUID());
		receipt.setCreateTime(new Date());
		receipt.setReceiptNumber(generateCode(1).get(0));
		List<DTOReceiptProducts> DTOReceiptProductsList = receipt.getDtoReceiptProductsList();//拿到收货单中的收货商品
		Long totalNotificationQuantity = DTOReceiptProductsList.stream()
				.mapToLong(DTOReceiptProducts::getNotificationQuantity)
				.sum();//获取收货单中的总通知收货量
		receipt.setReceiptTime(null);//清空收货时间
		receipt.setUpdateTime(new Date());
		receipt.setNoticeReceiptQuantity(totalNotificationQuantity);//设置收货单中的总通知收货量
		receipt.setReceiptQuantity(Constants.INITIALIZE);//将收货量设置为0，因为只是创建收货单还没有正式的开始收货

		int rows = receiptMapper.insertReceipt(receipt);

		//新增收货单详细
		insertReceiptProductsAdd(receipt);

		// 修改采购订单商品表中的相关数据
		DTOReceiptProductsList.forEach(receiptProduct -> {
			Long id = receiptProduct.getId();
			// 获取订单ID和产品ID
			Long ordersId = receiptProduct.getOrdersId();
			Long productId = receiptProduct.getProductId();
			String gtin = receiptProduct.getGtin();

			// 查询同一采购订单下当前商品的总已通知量
			Long notifiedCount = receiptMapper.selectReceiptNoticeQuantityByOrdersId(ordersId.toString(), productId, gtin);
			if (notifiedCount == null) {
				notifiedCount = 0L;
			}

			// 获取待到货量，进行空值判断
			Long waitingStock = receiptProduct.getWaitingStock();
			if (waitingStock == null) {
				waitingStock = 0L;
			}

			// 计算未通知量，确保不为负数
			Long unNotifiedQuantity = waitingStock - notifiedCount;
			unNotifiedQuantity = unNotifiedQuantity >= 0 ? unNotifiedQuantity : 0L;

			String detailsStatus = waitingStock == 0
					? Constants.FAIL
					: Constants.SUCCESS;


			// 更新采购订单商品表
			voOrdersProductMapper.updateById(new Long[]{id}, detailsStatus, unNotifiedQuantity, notifiedCount, gtin);

		});
		return rows;
	}

	/**
	 * 新增收货单信息
	 *
	 * @param receipt 收货单对象
	 */
//	public void insertReceiptProductsAdd(Receipt receipt) {
//		List<DTOReceiptProducts> DTOReceiptProductsList = receipt.getDtoReceiptProductsList();
//		String receiptId = receipt.getReceiptId();
//		if (StringUtils.isNotNull(DTOReceiptProductsList)) {
//			List<DTOReceiptProducts> list = new ArrayList<DTOReceiptProducts>();
//			for (DTOReceiptProducts receiptProducts : DTOReceiptProductsList) {
//				receiptProducts.setReceiptProductId(IdUtils.fastSimpleUUID());
//				receiptProducts.setReceiptId(receiptId);
//				receiptProducts.setUnnotifiedQuantity(Constants.INITIALIZE);//设置未通知量为0
//				receiptProducts.setNotifiedCount(receiptProducts.getNotificationQuantity());//设置已通知量为本次产品通知量
//				receiptProducts.setReceiptQuantity(Constants.INITIALIZE);//收货量
//				receiptProducts.setPendingQuantity(receiptProducts.getNotificationQuantity());//待检量
//				receiptProducts.setNotInspected(Constants.INITIALIZE);//未检量
//				receiptProducts.setQualityInspection(Constants.INITIALIZE);//质检中
//				receiptProducts.setCheckedQuantity(Constants.INITIALIZE);//已检量
//				receiptProducts.setAvailableQuantity(Constants.INITIALIZE);//可用量
//				receiptProducts.setDefectiveQuantity(Constants.INITIALIZE);//次品量
//				receiptProducts.setQualityStatus(QualityCheckStatus.NOT_INSPECTED.getCode());//质检状态
//				receiptProducts.setDeleteStatus(Constants.SUCCESS);//删除状态
//				receiptProducts.setAddTime(new Date());
//				list.add(receiptProducts);
//			}
//			if (list.size() > 0) {
//				receiptMapper.batchReceiptProducts(list);
//			}
//		}
//	}
	public void insertReceiptProductsAdd(Receipt receipt) {
		List<DTOReceiptProducts> dtoList = receipt.getDtoReceiptProductsList();
		String receiptId = receipt.getReceiptId();

		if (dtoList != null && !dtoList.isEmpty()) {
			// 分组：同一 SKU 的数据放在一起
			Map<String, List<DTOReceiptProducts>> groupBySku = dtoList.stream()
					.collect(Collectors.groupingBy(DTOReceiptProducts::getSku));

			// 最终需要插入的明细集合
			List<DTOReceiptProducts> processedList = new ArrayList<>();

			// 遍历每个 SKU 的分组
			for (Map.Entry<String, List<DTOReceiptProducts>> entry : groupBySku.entrySet()) {
				List<DTOReceiptProducts> group = entry.getValue();

				// 汇总该 SKU 分组所有记录中提交的通知收货量
				long groupNotificationSum = group.stream()
						.mapToLong(DTOReceiptProducts::getNotificationQuantity)
						.sum();

				// 用于记录已分配的总量
				long totalAllocated = 0;

				for (DTOReceiptProducts item : group) {
					// 可分配量 = 待到货量 - 已通知量（如果已通知量为空，则默认为0）
					long waitingStock = item.getWaitingStock() != null ? item.getWaitingStock() : 0L;
					long notifiedCount = item.getNotifiedCount() != null ? item.getNotifiedCount() : 0L;
					long available = waitingStock - notifiedCount;

					// 每个条目分配的数量是从总通知量中扣减，直到分配完所有剩余数量
					long remainingNotification = groupNotificationSum - totalAllocated;
					long allocated = Math.min(remainingNotification, available); // 分配剩余通知量和可分配量中的最小值

					// 更新已分配的总量
					totalAllocated += allocated;

					// 将分配后的数量赋值到通知收货量字段
					item.setNotificationQuantity(allocated);
				}

				// 计算初步分配合计
				long allocatedSum = group.stream().mapToLong(DTOReceiptProducts::getNotificationQuantity).sum(); // 得到已经分配完的合计通知收货量
				long leftover = groupNotificationSum - allocatedSum; // 计算还有多少没有分配完毕的通知收货量

				if (leftover > 0) {
					// 在本组内找到“待到货量”最大的记录
					DTOReceiptProducts candidate = group.stream().max(
							Comparator.comparingLong(item -> {
								// 计算待到货量，选择待到货量最大的记录
								long waitingStock = item.getWaitingStock() != null ? item.getWaitingStock() : 0L;
								long notifiedCount = item.getNotifiedCount() != null ? item.getNotifiedCount() : 0L;
								return waitingStock - notifiedCount; // 只考虑待到货量和已通知量
							})
					).orElse(null);

					if (candidate != null) {
						// 获取该候选记录的当前通知收货量
						long alreadyAllocated = candidate.getNotificationQuantity() != null ? candidate.getNotificationQuantity() : 0L;

						// 将剩余通知数量extra直接累加到该记录的通知收货量
						candidate.setNotificationQuantity(alreadyAllocated + leftover);
					}
				}

				// 遍历组内每条记录，补充其它字段
				for (DTOReceiptProducts item : group) {
					item.setReceiptProductId(IdUtils.fastSimpleUUID());
					item.setReceiptId(receiptId);
					item.setUnnotifiedQuantity(Constants.INITIALIZE);//设置未通知量为0
					item.setNotifiedCount(item.getNotificationQuantity());//设置已通知量为本次产品通知量
					item.setReceiptQuantity(Constants.INITIALIZE);//收货量
					item.setPendingQuantity(item.getNotificationQuantity());//待检量
					item.setNotInspected(Constants.INITIALIZE);//未检量
					item.setQualityInspection(Constants.INITIALIZE);//质检中
					item.setCheckedQuantity(Constants.INITIALIZE);//已检量
					item.setAvailableQuantity(Constants.INITIALIZE);//可用量
					item.setDefectiveQuantity(Constants.INITIALIZE);//次品量
					item.setQualityStatus(QualityCheckStatus.NOT_INSPECTED.getCode());//质检状态
					item.setDeleteStatus(Constants.SUCCESS);//删除状态
					item.setAddTime(new Date());
					processedList.add(item);
				}
			}

			if (!processedList.isEmpty()) {
				// 批量新增收货单详细
				receiptMapper.batchReceiptProducts(processedList);
			}
		}
	}


	/**
	 * 批量新增收货单信息
	 *
	 * @param receipts
	 * @return
	 */
	@Transactional
	@Override
	public int insertReceiptsBatch(List<Receipt> receipts) {
		List<String> numbers = generateCode(receipts.size());
		// 1. 准备收货单基础数据
		for (int i = 0; i < receipts.size(); i++) {
			Receipt receipt = receipts.get(i);
			receipt.setReceiptId(IdUtils.fastSimpleUUID());
			receipt.setCreateTime(new Date());
			receipt.setUpdateTime(new Date());
			receipt.setReceiptNumber(numbers.get(i));
			List<DTOReceiptProducts> dtoReceiptProductsList = receipt.getDtoReceiptProductsList();

			// 计算当前收货单的总通知收货量
			Long totalNotificationQuantity = dtoReceiptProductsList.stream()
					.mapToLong(DTOReceiptProducts::getWaitingStock)
					.sum();
			receipt.setNoticeReceiptQuantity(totalNotificationQuantity);
			receipt.setReceiptQuantity(Constants.INITIALIZE); // 初始化收货量为0

		}

		// 2. 批量插入收货单
		int insertedRows = receiptMapper.insertReceipts(receipts); // 自定义批量插入方法
		if (insertedRows <= 0) {
			throw new ServiceException("批量新增收货单失败");
		}

		// 3. 准备收货单详细数据
		List<DTOReceiptProducts> allReceiptProducts = new ArrayList<>();
		for (Receipt receipt : receipts) {
			String receiptId = receipt.getReceiptId();
			List<DTOReceiptProducts> dtoReceiptProductsList = receipt.getDtoReceiptProductsList();
			for (DTOReceiptProducts receiptProduct : dtoReceiptProductsList) {
				receiptProduct.setReceiptProductId(IdUtils.fastSimpleUUID());
				receiptProduct.setReceiptId(receiptId);
				receiptProduct.setUnnotifiedQuantity(Constants.INITIALIZE);
				receiptProduct.setNotificationQuantity(receiptProduct.getWaitingStock());
				receiptProduct.setNotifiedCount(receiptProduct.getWaitingStock());
				receiptProduct.setReceiptQuantity(Constants.INITIALIZE);
				receiptProduct.setPendingQuantity(receiptProduct.getWaitingStock());
				receiptProduct.setNotInspected(Constants.INITIALIZE);
				receiptProduct.setQualityInspection(Constants.INITIALIZE);
				receiptProduct.setCheckedQuantity(Constants.INITIALIZE);
				receiptProduct.setAvailableQuantity(Constants.INITIALIZE);
				receiptProduct.setDefectiveQuantity(Constants.INITIALIZE);
				receiptProduct.setQualityStatus(QualityCheckStatus.NOT_INSPECTED.getCode());
				receiptProduct.setDeleteStatus(Constants.SUCCESS);
				receiptProduct.setAddTime(new Date());
				allReceiptProducts.add(receiptProduct);
			}
		}

		// 4. 批量插入收货单详细
		if (!allReceiptProducts.isEmpty()) {
			receiptMapper.batchReceiptProducts(allReceiptProducts); // 自定义批量插入方法
		}

		// 5. 更新采购订单商品表
		updateOrdersProduct(receipts);

//		if(true){
//			throw new ServiceException("");
//		}
		return receipts.size();
	}

	/**
	 * 查询库存待检量详细
	 */
	@Override
	public List<OrdersProductVO> openInspectionQuantityDialog(OrdersProductVO vo) {
		if (vo.getProductId() == null) {
			throw new ServiceException("缺少查询参数产品id！");
		}
		List<OrdersProductVO> ordersProductVOS = ordersProductMapper.openInspectionQuantityDialog(vo);
		// 提取 productIds
		List<Long> productIds = ordersProductVOS.stream()
				.map(OrdersProductVO::getProductId)
				.collect(Collectors.toList());


		if (productIds.isEmpty() || ordersProductVOS.isEmpty()) {
			return new ArrayList<>();
		}


		Map<Integer, List<String>> collect = productImageMapper.selectProductImagesByProductId(productIds)
				.stream()
				.collect(Collectors.groupingBy(ProductImage::getProductId,
						Collectors.mapping(ProductImage::getProductImagePath, Collectors.toList())));


		ordersProductVOS.forEach(item -> {
			List<String> imagePath = collect.getOrDefault(item.getProductId().intValue(), new ArrayList<>());
			item.setProductImagePath(imagePath);
		});
		return ordersProductVOS;
	}

	private void updateOrdersProduct(List<Receipt> receipts) {
		// 构建批量更新数据
		List<OrdersProductUpdateDTO> updateList = new ArrayList<>();
		for (Receipt receipt : receipts) {
			for (DTOReceiptProducts receiptProduct : receipt.getDtoReceiptProductsList()) {
				Long ordersId = receiptProduct.getOrdersId();
				Long productId = receiptProduct.getProductId();
				String gtin = receiptProduct.getGtin();
				// 查询当前采购订单和商品的总已通知量
				Long notifiedCount = receiptMapper.selectReceiptNoticeQuantityByOrdersId(ordersId.toString(), productId, gtin);
				if (notifiedCount == null) {
					notifiedCount = 0L;
				}

				// 计算未通知量
//				Long waitingStock = receiptProduct.getWaitingStock() == null ? 0L : receiptProduct.getWaitingStock();
//				Long unNotifiedQuantity = Math.max(waitingStock - notifiedCount, 0);
				Long unNotifiedQuantity = 0L;//未通知量直接设置为0，因为是批量收货只能参于没有被通知收货过的产品

				// 设置状态（本次收货单数据已创建完毕之后查询出当前商品未完成收货的总已通知量与采购数量比较，如果说
//				String detailsStatus = notifiedCount.equals(receiptProduct.getTransferableNumber()) ?
//						Constants.FAIL : Constants.SUCCESS;
				String detailsStatus = receiptProduct.getWaitingStock() == 0
						? Constants.FAIL
						: Constants.SUCCESS;

				// 添加更新数据
				updateList.add(new OrdersProductUpdateDTO(new Long[]{receiptProduct.getId()}, detailsStatus, unNotifiedQuantity, notifiedCount));
			}
		}

		// 批量更新采购订单商品表
		if (!updateList.isEmpty()) {
			voOrdersProductMapper.batchUpdate(updateList); // 自定义批量更新方法
		}
	}


	/**
	 * 修改收货单
	 *
	 * @param receipt 收货单
	 * @return 结果
	 */
	@Transactional
	@Override
	public int updateReceipt(Receipt receipt) {
		//获取除了当前收货单其他收获单中商品的总通知量
		List<ReceiptProductVO> receiptProductVO = receiptMapper.selectReceiptProductNotifiedCountByReceiptId(receipt.getReceiptId());

		receipt.setUpdateTime(DateUtils.getNowDate());
		//删除当前收货明细单信息
		receiptMapper.deleteReceiptProductsByReceiptId(receipt.getReceiptId());
		//重新添加新的收货明细单信息并返回总通知收货量
		Integer noticeReceiptQuantity = insertReceiptProductsUpdate(receipt);
		receipt.setNoticeReceiptQuantity(Long.valueOf(noticeReceiptQuantity));
		//修改收货单的通知收货量
		int i = receiptMapper.updateReceipt(receipt);

		//修改【tb_orders_product】采购订单明细表的对应商品已通知量，未通知量
		updateOrdersProduct(receiptProductVO, receipt);
//		if(true){
//			throw new ServiceException("");
//		}
		return i;
	}

	/**
	 * 批量删除收货单
	 *
	 * @param receiptIds 需要删除的收货单主键
	 * @return 结果
	 */
	@Transactional
	@Override
	public int deleteReceiptByReceiptIds(String[] receiptIds) {
		//查询要删除的收货单下面的所有收货商品
		List<DTOReceiptProducts> DTOReceiptProductsList = receiptMapper.selectNotificationQuantity(receiptIds);
		DTOReceiptProductsList.forEach(receiptProducts -> {
			Long waitingStock = receiptProducts.getWaitingStock(); //拿到采购订单表中的待到货量
			Long notifiedCount = receiptProducts.getNotifiedCount(); //拿到采购订单表中的已通知量
			Long notificationQuantity = receiptProducts.getNotificationQuantity();//通知收货量
			// 计算删除该收货单后的已通知量
//			Long nowNotifiedCount = notifiedCount - notificationQuantity;
			Long nowNotifiedCount = Math.max(notifiedCount - notificationQuantity, 0);
			// 计算删除该收货单后的未通知量
//			Long nowUnNotifiedQuantity = waitingStock - nowNotifiedCount >= 0 ? waitingStock - nowNotifiedCount : 0;
			Long nowUnNotifiedQuantity = Math.max(waitingStock - nowNotifiedCount, 0);
			Long productId = receiptProducts.getProductId();
			Long ordersId = receiptProducts.getOrdersId();
			String gtin = receiptProducts.getGtin();

			voOrdersProductMapper.updateOrdersProduct(ordersId, productId, nowNotifiedCount, nowUnNotifiedQuantity, gtin);
//			voOrdersProductMapper.updateReceiptList(ordersId, productId, notificationQuantity);
		});
		receiptMapper.deleteReceiptProductsByReceiptIds(receiptIds);
		return receiptMapper.deleteReceiptByReceiptIds(receiptIds);
	}

	/**
	 * 删除收货单信息
	 *
	 * @param receiptId 收货单主键
	 * @return 结果
	 */
	@Transactional
	@Override
	public int deleteReceiptByReceiptId(String receiptId) {
		receiptMapper.deleteReceiptProductsByReceiptId(receiptId);
		return receiptMapper.deleteReceiptByReceiptId(receiptId);
	}


	/**
	 * 新增收货单信息
	 *
	 * @param receipt 收货单对象
	 */
//	public Integer insertReceiptProductsUpdate(Receipt receipt) {
//		List<DTOReceiptProducts> DTOReceiptProductsList = receipt.getDtoReceiptProductsList();//获取收货单中的商品信息
//		String receiptId = receipt.getReceiptId();
//		int noticeReceiptQuantity = 0;//存储本次收货单中所有产品的通知收货量
//		if (StringUtils.isNotNull(DTOReceiptProductsList)) {
//			List<DTOReceiptProducts> list = new ArrayList<DTOReceiptProducts>();
//			for (DTOReceiptProducts receiptProducts : DTOReceiptProductsList) {
//				receiptProducts.setReceiptId(receiptId);
//				receiptProducts.setNotifiedCount(receiptProducts.getNotificationQuantity());//设置已通知收货量等于修改后的通知收货量
//				receiptProducts.setPendingQuantity(receiptProducts.getNotificationQuantity());//修改待检量等于修改后的通知收货量
//				receiptProducts.setUpdateTime(DateUtils.getNowDate());
//				list.add(receiptProducts);
//				noticeReceiptQuantity += receiptProducts.getNotificationQuantity().intValue();
//
//				int NotificationQuantity = receiptProducts.getNotificationQuantity().intValue();//通知收货量
//				Integer unNotificationQuantity = receiptProducts.getWaitingStock().intValue() - receiptProducts.getNotifiedCount().intValue();//未通知量
//
//				//查询产品信息用于出现异常时提示
//				Product product = productMapper.selectProductById(receiptProducts.getProductId());
//				if (NotificationQuantity == 0) {
//					throw new RuntimeException("产品编号：" + product.getSku() + "，通知收货量不能为0！");
//				}
////				if (NotificationQuantity > unNotificationQuantity) {
////					throw new RuntimeException("产品编号：" + product.getSku() + "，超出产品库存数量范围或不能为0！");
////				}
//
//			}
//			if (list.size() > 0) {
//				receiptMapper.batchReceiptProducts(list);
//				return noticeReceiptQuantity;
//			}
//		}
//		return noticeReceiptQuantity;
//	}
	public Integer insertReceiptProductsUpdate(Receipt receipt) {
		List<DTOReceiptProducts> dtoList = receipt.getDtoReceiptProductsList();
		String receiptId = receipt.getReceiptId();
		int noticeReceiptQuantity = 0; // 存储本次收货单中所有产品的通知收货量

		if (dtoList != null && !dtoList.isEmpty()) {
			// 按 SKU 分组，确保一个 SKU 对应多个 GTIN 的场景也能统一处理
			Map<String, List<DTOReceiptProducts>> groupBySku = dtoList.stream()
					.collect(Collectors.groupingBy(DTOReceiptProducts::getSku));
			List<DTOReceiptProducts> processedList = new ArrayList<>();

			// 遍历每个 SKU 分组
			for (Map.Entry<String, List<DTOReceiptProducts>> entry : groupBySku.entrySet()) {
				List<DTOReceiptProducts> group = entry.getValue();

				// 计算该 SKU 分组所有记录中提交的通知收货量总和
				long groupNotificationSum = group.stream()
						.mapToLong(DTOReceiptProducts::getNotificationQuantity)
						.sum();

				if (groupNotificationSum == 0) {
					throw new ServiceException("产品" + entry.getKey() + "，通知收货量不能为0！");
				}

				// 用于记录已分配的数量
				long totalAllocated = 0;

				// 按顺序分配各记录的通知收货量（分配的上限是：待到货量 - 已通知量）
				for (DTOReceiptProducts item : group) {
					// 获取当前记录的待到货量和已通知量（空值按 0 处理）
					long waitingStock = item.getWaitingStock() != null ? item.getWaitingStock() : 0L;
					long currentNotified = item.getNotifiedCount() != null ? item.getNotifiedCount() : 0L;
					long available = waitingStock - currentNotified; // 可分配的上限

					long remainingNotification = groupNotificationSum - totalAllocated;
					long allocated = Math.min(remainingNotification, available);

					// 更新当前记录的分配结果
					item.setNotificationQuantity(allocated);

					// 更新已分配总量
					totalAllocated += allocated;
				}

				// 如果分配后还有剩余，将剩余数量补充到可分配上限最大的记录中
				long allocatedSum = group.stream()
						.mapToLong(DTOReceiptProducts::getNotificationQuantity)
						.sum();
				long leftover = groupNotificationSum - allocatedSum;
				if (leftover > 0) {
					// 找出待到货量 - 已通知量最大的记录作为候选记录
					DTOReceiptProducts candidate = group.stream().max(
							Comparator.comparingLong(item -> {
								long waitingStock = item.getWaitingStock() != null ? item.getWaitingStock() : 0L;
								long currentNotified = item.getNotifiedCount() != null ? item.getNotifiedCount() : 0L;
								return waitingStock - currentNotified;
							})
					).orElse(null);
					if (candidate != null) {
						candidate.setNotificationQuantity(candidate.getNotificationQuantity() + leftover);
					}
				}

				// 遍历组内每条记录，补充其它字段并累加本组的通知收货量
				for (DTOReceiptProducts item : group) {
					item.setReceiptProductId(IdUtils.fastSimpleUUID());
					item.setReceiptId(receiptId);
					// 在更新时，通常将修改后的通知收货量复制到已通知量和待检量字段中
					item.setNotifiedCount(item.getNotificationQuantity());
					item.setPendingQuantity(item.getNotificationQuantity());
					// 设置未通知量为初始值（如 0）
					item.setUnnotifiedQuantity(Constants.INITIALIZE);
					// 收货量、检验量、质检状态等按照业务逻辑设置
					item.setReceiptQuantity(Constants.INITIALIZE);
					item.setNotInspected(Constants.INITIALIZE);
					item.setQualityInspection(Constants.INITIALIZE);
					item.setCheckedQuantity(Constants.INITIALIZE);
					item.setAvailableQuantity(Constants.INITIALIZE);
					item.setDefectiveQuantity(Constants.INITIALIZE);
					item.setQualityStatus(QualityCheckStatus.NOT_INSPECTED.getCode());
					item.setDeleteStatus(Constants.SUCCESS);
					item.setUpdateTime(DateUtils.getNowDate());

					processedList.add(item);
					// 累加到收货单总通知数量
					noticeReceiptQuantity += item.getNotificationQuantity().intValue();
				}
			}

			if (!processedList.isEmpty()) {
				// 批量新增收货单详细记录
				receiptMapper.batchReceiptProducts(processedList);
				return noticeReceiptQuantity;
			}
		}
		return noticeReceiptQuantity;
	}

//    private String generateCode(int size){
//        // 获取当前日期
//        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
//        String currentDate = dateFormat.format(new Date());
//
//        //获取序列号
//        String receiptNumber = receiptMapper.selectReceiptNumber();
//        String number;
//        // ...根据自己的业务逻辑实现获取序列号的方法
//        if(StringUtils.isEmpty(receiptNumber)){
////            number = Constants.INBOUND_NUMBER;
//            number = String.format("%04d", (NumberUtils.parseNumber(Constants.INBOUND_NUMBER,Long.class)+(size)));
//        }else{
//            number = String.format("%04d", (NumberUtils.parseNumber(receiptNumber.substring(10),Long.class)+(size+1)));
//        }
//        // 拼接生成的代码
//        String code = Constants.RECEIPT_NUMBER + currentDate + number;
//        return code;
//    }

	/**
	 * 生成随机数
	 *
	 * @param
	 * @return
	 */
	private List<String> generateCode(Integer count) {
		synchronized (this) {  // 使用同步块，防止多线程并发访问
			// 获取当前日期
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
			String currentDate = dateFormat.format(new Date());

			// 获取最后一个收货单编号，在事务中加锁（使用 FOR UPDATE）
			String lastReceiptNumber = receiptMapper.selectLastReceiptNumberForUpdate();

			// 生成的编号列表
			List<String> generatedCodes = new ArrayList<>();

			// 如果没有找到最后一个编号，或者日期不匹配，说明是当天的第一个收货单
			String number;
			if (StringUtils.isEmpty(lastReceiptNumber) || !lastReceiptNumber.substring(2, 10).equals(currentDate)) {
				// 如果没有找到或者日期不匹配，生成从CR202411290001开始
				number = Constants.INBOUND_NUMBER;
			} else {
				// 提取编号中的序列部分，并加一
				String lastNumberStr = lastReceiptNumber.substring(10); // 编号格式：CR + 日期（8位） + 序号（4位）
				long lastNumber = Long.parseLong(lastNumberStr);
				number = String.format("%04d", lastNumber + 1);
			}

			// 生成指定数量的编号
			for (int i = 0; i < count; i++) {
				String code = Constants.RECEIPT_NUMBER + currentDate + number;
				// 检查生成的编号是否已存在，避免并发冲突
				int retryCount = 0;
				while (receiptMapper.checkReceiptNumberExists(code) > 0 && retryCount < 5) {
					// 如果编号已经存在，重新生成
					retryCount++;
					String lastReceiptNumberRetry = receiptMapper.selectLastReceiptNumberForUpdate();
					if (StringUtils.isEmpty(lastReceiptNumberRetry) || !lastReceiptNumberRetry.substring(2, 10).equals(currentDate)) {
						number = Constants.INBOUND_NUMBER;
					} else {
						String lastNumberStrRetry = lastReceiptNumberRetry.substring(10);
						long lastNumberRetry = Long.parseLong(lastNumberStrRetry);
						number = String.format("%04d", lastNumberRetry + 1);
					}
					code = Constants.RECEIPT_NUMBER + currentDate + number;
				}

				if (retryCount >= 5) {
					// 达到重试次数限制，可以抛出异常或返回失败标志
					throw new RuntimeException("Failed to generate unique receipt number after 5 retries.");
				}

				// 将生成的编号添加到列表
				generatedCodes.add(code);

				// 更新编号的序号
				long currentNumber = Long.parseLong(number);
				number = String.format("%04d", currentNumber + 1);
			}

			return generatedCodes;
		}
	}

	/**
	 * 修改【tb_orders_product】采购订单明细表的对应商品已通知量，未通知量
	 *
	 * @param existingProducts
	 * @param receipt
	 */
	private void updateOrdersProduct(List<ReceiptProductVO> existingProducts, Receipt receipt) {
		// 确保 existingProducts 不为 null
		if (existingProducts == null) {
			existingProducts = Collections.emptyList();
		}

		// 确保 receipt.getDtoReceiptProductsList() 不为 null
		List<DTOReceiptProducts> updatedProducts = receipt.getDtoReceiptProductsList();
		if (updatedProducts == null) {
			updatedProducts = Collections.emptyList();
		}

		// 处理删除的产品
		for (ReceiptProductVO existingProduct : existingProducts) {
			Long existingProductId = existingProduct.getProductId();
			String gtin = existingProduct.getGtin();
			// 检查 existingProductId 是否为 null
			if (existingProductId == null) {
				continue; // 或者根据业务逻辑进行处理
			}

			// 获取 ordersProductId，并进行空值检查
			String orderProductId = existingProduct.getOrdersProductId() != null ? existingProduct.getOrdersProductId().toString() : null;
			if (orderProductId == null) {
				continue; // 或者根据业务逻辑进行处理
			}

			boolean existsInUpdatedList = updatedProducts.stream()
					.anyMatch(updated -> updated.getProductId() != null && updated.getProductId().equals(existingProductId) && updated.getGtin().equals(gtin));

			// 如果现有产品不在更新的产品列表中，说明该产品被删除
			if (!existsInUpdatedList) {
				// 获取已通知量和待到货量，进行空值检查
				Long newNotifiedCount = existingProduct.getOtherNotifiedCount() != null ? existingProduct.getOtherNotifiedCount() : 0L;
				Long waitingStock = existingProduct.getWaitingStock() != null ? existingProduct.getWaitingStock() : 0L;

				// 计算回滚后的数据
				Long newUnNotifiedQuantity = Math.max(waitingStock - newNotifiedCount, 0); // 计算未通知量

				// 更新采购订单明细表的对应商品
				voOrdersProductMapper.updateOrdersProductByParams(orderProductId, newNotifiedCount, newUnNotifiedQuantity, DateUtils.getNowDate());
			}
		}

		// 遍历前端传来的新数据
		for (DTOReceiptProducts updatedProduct : updatedProducts) {
			// 获取产品id，进行空值检查
			Long productId = updatedProduct.getProductId();
			if (productId == null) {
				continue;
			}
			String gtin = updatedProduct.getGtin(); // GTIN

			// 获取待到货量和已通知量，进行空值检查
			Long waitingStock = updatedProduct.getWaitingStock() != null ? updatedProduct.getWaitingStock() : 0L;
			Long notifiedCount = updatedProduct.getNotifiedCount() != null ? updatedProduct.getNotifiedCount() : 0L;
			Long notificationQuantity = updatedProduct.getNotificationQuantity() != null ? updatedProduct.getNotificationQuantity() : 0L;

			// 获取采购订单明细id，进行空值检查
			String ordersProductId = updatedProduct.getOrdersProductId();
			if (ordersProductId == null) {
				continue; // 或者根据业务逻辑进行处理
			}

			// 采购订单id，进行空值检查
			Long ordersId = updatedProduct.getOrdersId() != null ? updatedProduct.getOrdersId() : 0L;

			// 查找更新后的产品是否在现有产品中存在
			Optional<ReceiptProductVO> existingProductOpt = existingProducts.stream()
					.filter(p -> p.getProductId() != null && p.getProductId().equals(productId) && p.getGtin().equals(gtin))
					.findFirst();

			if (existingProductOpt.isPresent()) {
				// 更新现有产品的已通知量和未通知量
				ReceiptProductVO existingProduct = existingProductOpt.get();

				Long otherNotifiedCount = existingProduct.getOtherNotifiedCount() != null ? existingProduct.getOtherNotifiedCount() : 0L;

				// 计算更新后的产品已通知量
				Long newNotifiedCount = otherNotifiedCount + notificationQuantity;

				// 计算更新后的产品未通知量
				Long newUnNotifiedQuantity = Math.max(waitingStock - newNotifiedCount, 0);

				// 执行更新
				voOrdersProductMapper.updateOrdersProductByParams(ordersProductId, newNotifiedCount, newUnNotifiedQuantity, DateUtils.getNowDate());
			} else {
				// 如果不存在，则视为新增处理

				// 计算更新后的产品已通知量，因为是新增产品，那么通知收货量是多少，赋值后的已通知量就是多少
				Long newNotifiedCount = notificationQuantity;

				// 计算更新后的产品未通知量
				Long newUnNotifiedQuantity = Math.max(waitingStock - newNotifiedCount, 0);

				// 执行更新
				voOrdersProductMapper.updateOrdersProductByParams(ordersProductId, newNotifiedCount, newUnNotifiedQuantity, DateUtils.getNowDate());
			}
		}
	}


	/**
	 * 确认收单
	 *
	 * @param receipt 收货单
	 * @return 结果
	 */
	@Transactional
	@Override
	public int updateReceiptConfirm(Receipt receipt) {
		// 查询数据库，校验数据是否存在
		Receipt byId = receiptMapper.selectById(receipt.getReceiptId());
		if (byId == null) {
			// 如果不存在，抛出异常
			throw new ServiceException("当前修改的数据不存在，请刷新页面重试。");
		}
		// 修改采购商品订单表中的相关参数
		Integer receiptQuantity = updateReceiptProductsReceiptQuantity(receipt);
		receipt.setReceiptQuantity(Long.valueOf(receiptQuantity));
		receipt.setConsignee(new BaseController().getNickname());// 设置收货人为当前操作人
		receipt.setReceiptTime(DateUtils.getNowDate());         // 设置收货时间为当前时间
		receipt.setReceiptStatus(Constants.STATUS_ONE);          // 将收获单的收货状态设置为已完成
		receipt.setUpdateTime(DateUtils.getNowDate());
//		if(true){
//			throw new ServiceException("");
//		}
		return receiptMapper.updateReceipt(receipt);
	}

	/**
	 * 查询是否可以进行收货
	 *
	 * @param receiptId
	 * @return
	 */
	@Override
	public int validateBeforeReceiving(String receiptId) {
		// 查询数据库，校验数据是否存在
		Receipt receipt = receiptMapper.selectById(receiptId);
		if (receipt == null) {
			// 如果不存在，抛出异常
			throw new ServiceException("当前收货单数据不存在，请刷新页面重试。");
		}

		// 获取收货单商品详细
		List<ReceiptProducts> receiptDetails = receiptProductsMapper.selectList(
				new LambdaQueryWrapper<>(ReceiptProducts.class)
						.eq(ReceiptProducts::getReceiptId, receiptId)
						.eq(ReceiptProducts::getDeleteStatus, Constants.NOT_DELETED_STATUS)
		);

		// 校验收货单商品详细是否为空
		if (receiptDetails == null || receiptDetails.isEmpty()) {
			throw new ServiceException("收货单商品详情数据不存在，请刷新页面重试。");
		}

		// 获取采购订单号和产品ID集合
		Long ordersId = receipt.getOrdersId();
		List<Integer> productIds = receiptDetails.stream()
				.map(ReceiptProducts::getProductId)
				.distinct() // 去重，避免重复的 productId
				.collect(Collectors.toList());

		// 查询采购订单详细中对应产品的待到货量
		List<OrdersProduct> ordersProducts = ordersProductMapper.selectList(
				new LambdaQueryWrapper<>(OrdersProduct.class)
						.in(OrdersProduct::getProductId, productIds)
						.eq(OrdersProduct::getOrdersId, ordersId)
		);

		// 校验采购订单详细是否为空
		if (ordersProducts == null || ordersProducts.isEmpty()) {
			throw new ServiceException("收货单中对应的采购订单详情数据不存在，请刷新页面重试。");
		}

		// 检查是否所有待收货量都为 0
		boolean allZeroWaitingStock = ordersProducts.stream()
				.allMatch(detail -> detail.getWaitingStock() == 0);

		if (allZeroWaitingStock) {
			throw new ServiceException("错误：采购单所有商品待收货量为 0，无法收货，请核实单据状态。");
		}

		return 1; // 校验通过，返回成功标志
	}


//	/**
//	 * 修改采购订单商品表、收货单详细表相关数据
//	 *
//	 * @param receipt
//	 * @return
//	 */
//	public Integer updateReceiptProductsReceiptQuantity(Receipt receipt) {
//		List<DTOReceiptProducts> receiptProductsList = receipt.getDtoReceiptProductsList();
//		if (receiptProductsList == null || receiptProductsList.isEmpty()) {
//			throw new ServiceException("收货产品列表不能为空！");
//		}
//
//		int totalReceiptQuantity = 0;
//		List<DTOReceiptProducts> updateList = new ArrayList<>();
//		// 获取一次当前时间，避免在循环中多次调用
//		Date currentDate = DateUtils.getNowDate();
//
//		for (DTOReceiptProducts receiptProduct : receiptProductsList) {
//			// 设置更新时间并加入更新列表
//			receiptProduct.setUpdateTime(currentDate);
//			updateList.add(receiptProduct);
//
//			int nowReceiptQuantity = receiptProduct.getReceiptQuantity() != null ? receiptProduct.getReceiptQuantity().intValue() : 0;
//			if (nowReceiptQuantity <= 0) {
//				Product product = productMapper.selectProductById(receiptProduct.getProductId());
//				throw new ServiceException("产品编号：" + product.getSku() + "，收货量不能为0或负数！");
//			}
//			totalReceiptQuantity += nowReceiptQuantity;
//
//			// 查询相关采购订单商品数据
//			OrdersProduct op = ordersProductMapper.selectOne(
//					Wrappers.<OrdersProduct>lambdaQuery()
//							.eq(OrdersProduct::getOrdersId, receipt.getOrdersId())
//							.eq(OrdersProduct::getProductId, receiptProduct.getProductId())
//			);
//			if (op == null) {
//				throw new ServiceException("未找到对应的采购订单商品数据，订单ID：" + receipt.getOrdersId() +
//						"，产品ID：" + receiptProduct.getProductId());
//			}
//
//			Long notifiedCount = op.getNotifiedCount() != null ? op.getNotifiedCount() : 0L;
//			Long waitingStock = op.getWaitingStock() != null ? op.getWaitingStock() : 0L;
//
//			//【修改点】：允许超量收货，移除了原来的待到货量检查逻辑
//			// 原代码：如果(receiptProduct.getReceiptQuantity() > waitingStock)则抛出异常
//			// if (waitingStock < receiptProduct.getReceiptQuantity()) {
//			//     throw new ServiceException("产品ID：" + receiptProduct.getProductProNo() +
//			//             "，本次收货量超出来源单据待收货量，请检查确认");
//			// }
//
//			// 计算新的待到货量、已通知量、未通知量
//			long nowWaitingStock = waitingStock - receiptProduct.getReceiptQuantity();
//			long nowNotifiedCount = notifiedCount - receiptProduct.getNotificationQuantity();
//			long nowUnNotifiedQuantity = nowWaitingStock - nowNotifiedCount;
//
//			// 如果待到货量小于或等于0，归零；允许超量收货时，超出的部分不产生负数
//			if (nowWaitingStock <= 0) {
//				nowWaitingStock = 0L;
//				nowNotifiedCount = 0L;
//				nowUnNotifiedQuantity = 0L;
//			} else {
//				nowUnNotifiedQuantity = Math.max(nowUnNotifiedQuantity, 0L);
//			}
//
//			// 更新采购订单商品数据
//			ordersProductMapper.update(null,
//					new LambdaUpdateWrapper<OrdersProduct>()
//							.eq(OrdersProduct::getOrdersId, receipt.getOrdersId())
//							.eq(OrdersProduct::getProductId, receiptProduct.getProductId())
//							.set(OrdersProduct::getWaitingStock, nowWaitingStock)
//							.set(OrdersProduct::getNotifiedCount, nowNotifiedCount)
//							.set(OrdersProduct::getUnnotifiedQuantity, nowUnNotifiedQuantity)
//							.set(OrdersProduct::getUpdateTime, currentDate)
//			);
//		}
//
//		// 批量更新收货产品数据。MyBatis 的 foreach 会自动处理空列表
//		receiptMapper.batchUpdateReceiptProducts(updateList);
//
//		return totalReceiptQuantity;
//	}
	/**
	 * 修改采购订单商品表、收货单详细表相关数据
	 *
	 * @param receipt
	 * @return
	 */
	public Integer updateReceiptProductsReceiptQuantity(Receipt receipt) {
		List<DTOReceiptProducts> receiptProductsList = receipt.getDtoReceiptProductsList();
		if (receiptProductsList == null || receiptProductsList.isEmpty()) {
			throw new ServiceException("收货产品列表不能为空！");
		}

		int totalReceiptQuantity = 0;
		List<DTOReceiptProducts> updateList = new ArrayList<>();
		Date currentDate = DateUtils.getNowDate();

		for (DTOReceiptProducts receiptProduct : receiptProductsList) {
			int nowReceiptQty = receiptProduct.getReceiptQuantity() == null
					? 0 : receiptProduct.getReceiptQuantity().intValue();
			if (nowReceiptQty <= 0) {
				Product product = productMapper.selectProductById(receiptProduct.getProductId());
				throw new ServiceException("产品：" + product.getSku() + "，收货量不能为0或负数！");
			}
			totalReceiptQuantity += nowReceiptQty;

			// 如果没有 GTIN，沿用「整 SKU 一条」的逻辑
			List<String> gtins = receiptProduct.getGtins();
			if (gtins == null || gtins.isEmpty()) {
				// 1. 更新 orders_product
				OrdersProduct op = ordersProductMapper.selectOne(
						Wrappers.<OrdersProduct>lambdaQuery()
								.eq(OrdersProduct::getOrdersId, receipt.getOrdersId())
								.eq(OrdersProduct::getProductId, receiptProduct.getProductId())
				);
				if (op == null) {
					throw new ServiceException("未找到对应的采购订单商品数据，订单ID："
							+ receipt.getOrdersId() + "，产品ID：" + receiptProduct.getProductId());
				}
				long waitingStock = op.getWaitingStock() == null ? 0L : op.getWaitingStock();
				long notifiedCount = op.getNotifiedCount() == null ? 0L : op.getNotifiedCount();
				int notifQty = receiptProduct.getNotificationQuantity() == null
						? 0 : receiptProduct.getNotificationQuantity().intValue();

				// 计算新值（允许超量收货，且不出现负数）
				long newWaitingStock = Math.max(0L, waitingStock - nowReceiptQty);
				long newNotifiedCount = Math.max(0L, notifiedCount - notifQty);
				long newUnnotifiedQuantity = Math.max(0L, newWaitingStock - newNotifiedCount);

				ordersProductMapper.update(null,
						new LambdaUpdateWrapper<OrdersProduct>()
								.eq(OrdersProduct::getOrdersId, receipt.getOrdersId())
								.eq(OrdersProduct::getProductId, receiptProduct.getProductId())
								.set(OrdersProduct::getWaitingStock, newWaitingStock)
								.set(OrdersProduct::getNotifiedCount, newNotifiedCount)
								.set(OrdersProduct::getUnnotifiedQuantity, newUnnotifiedQuantity)
								.set(OrdersProduct::getUpdateTime, currentDate)
				);

				// 2. 批量更新 receipt_products —— 用前端传回的 receiptProductId
				receiptProduct.setUpdateTime(currentDate);
				updateList.add(receiptProduct);
			} else {
				// 有多个 GTIN，按 GTIN 拆分处理
				int remainingReceipt = nowReceiptQty;
				int remainingNotif = receiptProduct.getNotificationQuantity() == null
						? 0 : receiptProduct.getNotificationQuantity().intValue();

				// 2.1 按 GTIN 逐条分配
				for (String gtin : gtins) {
					if (remainingReceipt <= 0) break;
					// a. 更新 orders_product
					OrdersProduct op = ordersProductMapper.selectOne(
							Wrappers.<OrdersProduct>lambdaQuery()
									.eq(OrdersProduct::getOrdersId, receipt.getOrdersId())
									.eq(OrdersProduct::getProductId, receiptProduct.getProductId())
									.eq(OrdersProduct::getGtin, gtin)
					);
					if (op == null) {
						throw new ServiceException("未找到采购订单商品，订单ID：" + receipt.getOrdersId()
								+ "，产品ID：" + receiptProduct.getProductId() + "，GTIN：" + gtin);
					}
					long available = op.getWaitingStock() == null ? 0L : op.getWaitingStock(); // 可分配的收货量为当前这个产品的待到货量
					long notifiedCount = op.getNotifiedCount() == null ? 0L : op.getNotifiedCount();  // 当前采购商品的已通知收货量
					if (available <= 0) {
						continue;
					}
					int allocReceipt = (int) Math.min(remainingReceipt, available); // 本次可分配的数量（剩余收货量，待到货量）
					int allocNotif = (int) Math.min(remainingNotif, notifiedCount);
					remainingReceipt -= allocReceipt;
					remainingNotif -= allocNotif;

					long newWaiting = Math.max(0L, op.getWaitingStock() - allocReceipt);
					long newNotified = Math.max(0L, op.getNotifiedCount() - allocNotif);
					long newUnnotif = Math.max(0L, newWaiting - newNotified);
					ordersProductMapper.update(null,
							new LambdaUpdateWrapper<OrdersProduct>()
									.eq(OrdersProduct::getOrdersId, receipt.getOrdersId())
									.eq(OrdersProduct::getProductId, receiptProduct.getProductId())
									.eq(OrdersProduct::getGtin, gtin)
									.set(OrdersProduct::getWaitingStock, newWaiting)
									.set(OrdersProduct::getNotifiedCount, newNotified)
									.set(OrdersProduct::getUnnotifiedQuantity, newUnnotif)
									.set(OrdersProduct::getUpdateTime, currentDate)
					);

					// b. 更新对应的 receipt_products
					DTOReceiptProducts dbRp = receiptProductsMapper.selectByReceiptIdAndProductIdAndGTIN(
							receipt.getReceiptId(),
							receiptProduct.getProductId(),
							gtin
					);
					if (dbRp == null) {
						throw new ServiceException("未找到收货明细，receiptId：" + receipt.getReceiptId()
								+ "，productId：" + receiptProduct.getProductId() + "，gtin：" + gtin);
					}
					dbRp.setReceiptQuantity((long) allocReceipt);
					dbRp.setNotInspected((long) allocReceipt);
					dbRp.setUpdateTime(currentDate);
					updateList.add(dbRp);
				}

				// 2.2 如果还有剩余，补给待到货量最大的那条
				if (remainingReceipt > 0) {
					String candidateGtin = gtins.stream()
							.max(Comparator.comparing(gtin -> {
								OrdersProduct t = ordersProductMapper.selectOne(
										Wrappers.<OrdersProduct>lambdaQuery()
												.eq(OrdersProduct::getOrdersId, receipt.getOrdersId())
												.eq(OrdersProduct::getProductId, receiptProduct.getProductId())
												.eq(OrdersProduct::getGtin, gtin)
								);
								return t == null ? 0L : t.getWaitingStock();
							}))
							.orElse(null);

					if (candidateGtin != null) {
						OrdersProduct op2 = ordersProductMapper.selectOne(
								Wrappers.<OrdersProduct>lambdaQuery()
										.eq(OrdersProduct::getOrdersId, receipt.getOrdersId())
										.eq(OrdersProduct::getProductId, receiptProduct.getProductId())
										.eq(OrdersProduct::getGtin, candidateGtin)
						);
						long newWaiting = Math.max(0L, op2.getWaitingStock() - remainingReceipt);
						long newNotified = Math.max(0L, op2.getNotifiedCount() - remainingNotif);
						long newUnnotif = Math.max(0L, newWaiting - newNotified);
						ordersProductMapper.update(null,
								new LambdaUpdateWrapper<OrdersProduct>()
										.eq(OrdersProduct::getOrdersId, receipt.getOrdersId())
										.eq(OrdersProduct::getProductId, receiptProduct.getProductId())
										.eq(OrdersProduct::getGtin, candidateGtin)
										.set(OrdersProduct::getWaitingStock, newWaiting)
										.set(OrdersProduct::getNotifiedCount, newNotified)
										.set(OrdersProduct::getUnnotifiedQuantity, newUnnotif)
										.set(OrdersProduct::getUpdateTime, currentDate)
						);

						// 更新收货单明细
						// 先从 receipt_products 表拉出这条记录的基础对象
						DTOReceiptProducts dbRp2 = receiptProductsMapper.selectByReceiptIdAndProductIdAndGTIN(
								receipt.getReceiptId(),
								receiptProduct.getProductId(),
								candidateGtin
						);
						if (dbRp2 == null) {
							throw new ServiceException("未找到收货明细，receiptId：" + receipt.getReceiptId()
									+ "，productId：" + receiptProduct.getProductId()
									+ "，gtin：" + candidateGtin);
						}

						// 尝试在 updateList 里找已经加过一次的那条
						boolean merged = false;
						for (DTOReceiptProducts u : updateList) {
							if (Objects.equals(u.getReceiptId(), dbRp2.getReceiptId())
									&& Objects.equals(u.getProductId(), dbRp2.getProductId())
									&& Objects.equals(u.getGtin(), dbRp2.getGtin())) {
								// 找到后直接累加，而不是覆盖
								long newQty = u.getReceiptQuantity() + remainingReceipt;
								u.setReceiptQuantity(newQty);
								u.setNotInspected(newQty);
								u.setUpdateTime(currentDate);
								merged = true;
								break;
							}
						}

						// 如果之前没加入过，再新增一条
						if (!merged) {
							dbRp2.setReceiptQuantity((long) remainingReceipt);
							dbRp2.setNotInspected((long) remainingReceipt);
							dbRp2.setUpdateTime(currentDate);
							updateList.add(dbRp2);
						}
					}
				}
			}
		}

		// 批量更新 receipt_products
		receiptMapper.batchUpdateReceiptProducts(updateList);
		return totalReceiptQuantity;
	}
}
